<?php

class Application_Model_StudyMapper extends Application_Model_Mapper
{
    const LIMIT_TERMS = 10;
    static $cacheTags = array();
    /**
     * @param $options
     * @param int $page
     * @return array(terms => array(Application_Model_Term), paginator => Zend_Paginator)
     */
    public function getTermsByOptions($options, $page = 1)
    {

        if (isset($options['query']) && !empty($options['query'])) {
            return $this->searchTerm($options['query'], $page);
        }

        $select = $this->db->select()->from('terms');

        if (isset($options['tag_id']) && !empty($options['tag_id'])) {
            $select->join('terms_to_tags', 'terms_to_tags.term_id = terms.term_id')->where('terms_to_tags.tag_id = ? ', $options['tag_id']);
        }

        if (isset($options['first_symbol']) && !empty($options['first_symbol'])) {
            $select->where('first_symbol = ?', $options['first_symbol']);
        }

        $select->order('terms.term_id DESC');
        return $this->infoTerm($select, $page);
    }

    public function infoTerm($select, $page)
    {

        $adapter   = new Zend_Paginator_Adapter_DbSelect($select);
        $paginator = new Zend_Paginator($adapter);
        $paginator->setCurrentPageNumber($page);
        $paginator->setItemCountPerPage(self::LIMIT_TERMS);
        $terms = array();

        if (!empty($paginator)) {
            foreach ($paginator as $item) {
                $terms[] = $this->getTermById($item['term_id']);
            }
        }

        return array('terms' => $terms, 'paginator' => $paginator);
    }

    public function fetchAllTags()
    {
        if (!empty(self::$cacheTags)) {
            return self::$cacheTags;
        }

        $select = $this->db->select()->from(array('t' => 'tags'),array('count(tg.term_id) as count_terms, tg.tag_id as tag_id, t.tag_name as tag_name'))->join(array('tg' => 'terms_to_tags'), 't.tag_id = tg.tag_id')->group('tg.tag_id')->order('tg.tag_id ASC');
        $result = $this->db->fetchAll($select);
        $tags = array();

        foreach ($result as $options) {
            $model = new Application_Model_Tag($options);
            $tags[$options['tag_id']] = $model;
        }

        self::$cacheTags = $tags;
        return $tags;
    }

    public function fetchAllFirstSymbols()
    {
        $select = $this->table->select()
                ->from($this->table, array('COUNT(term_id) as count_terms', 'first_symbol'))
                ->where('first_symbol IS NOT NULL')->group('first_symbol')
                ->order('first_symbol ASC');

        $result = $this->table->fetchAll($select)->toArray();
        return $result;
    }

    public function insertTerm($options)
    {
        return parent::insert($options);
    }

    public function deleteTerm($id)
    {
        parent::del('term_id', $id);
        $tagsToTerm = new Application_Model_DbTable_TermsToTags();
        $tagsToTerm->delete("term_id = {$id}");
        return true;
    }

    public function updateTerm($termOptions, $idTerm, $tagsIds = array())
    {
        if (!empty($termOptions)) {
            $where['term_id = ?'] = $idTerm;
            parent::update($termOptions, $where);
        }

        if (!empty($tagsIds)) {
            $tableLinkTags = new Application_Model_DbTable_TermsToTags();

            foreach ($tagsIds as $tagId) {
                 $tableLinkTags->insert(array('term_id' => $idTerm, 'tag_id' => $tagId));
            }
        }
    }

    public function getTagByName($name)
    {
        $select = $this->table->select()->where('tag_name LIKE ? ', $name);
        $tagOptions = $this->table->fetchRow($select);

        if ($tagOptions) {
            $model = clone $this->model;
            $model->setOptions($tagOptions->toArray());
            return $model;
        } else {
            return null;
        }
    }

    public function getTermById($id)
    {
        if (!$id && !is_int($id)) {
            return null;
        }

        //TODO сделать кеширование терминов
        $term = parent::getById($id);

        if ($term) {

            $tagsRows = $this->db->fetchAll($this->db->select()->from('terms_to_tags', array('term_id', 'tag_id'))->where('term_id = ?', $term->getTermId()));

            if ($tagsRows) {
                if (!self::$cacheTags) {
                    $this->fetchAllTags();
                }

                $tags = array();
                foreach ($tagsRows as $row) {
                    if (array_key_exists($row['tag_id'], self::$cacheTags)) {
                        $tags[$row['tag_id']] = self::$cacheTags[$row['tag_id']];
                    }
                }

                $term->setOptions(array('tags' => $tags));
            }

            return $term;
        }

        return null;
    }

    public function getTermsByIds($ids)
    {
        //TODO реализовать этот метод
    }

    public static function tagsToJsonForCloud($tags)
    {
        $result = array();
        if ($tags) {
            foreach ($tags as $tag) {
                /** @var $tag Application_Model_Tag */
                $result[] = array(
                    'text'   => $tag->getTagName(),
                    'weight' => $tag->getCountTerms(),
                    'link'   => 'http://mynotes.local/study?tag=' . $tag->getTagId(),
                );
            }
        }

        return json_encode($result);
    }

    public function getTags()
    {
        return $this->table->fetchAll()->toArray();
    }

    public function deleteTagFromTerm($termId, $tagId)
    {
        return $this->table->delete("term_id = {$termId} AND tag_id = {$tagId}");
    }

    public function getSearchText($options)
    {
        $text = '';
        if ((isset($options['tag_id']) && !empty($options['tag_id'])) ||
            (isset($options['first_symbol']) && !empty($options['first_symbol'])) ||
            (isset($options['query']) && !empty($options['query']))
        ) {
            $text = 'Показаны термины ';
        }

        if (isset($options['first_symbol']) && !empty($options['first_symbol'])) {
            $text .= ',которые начинаются на букву "<b>' . $options['first_symbol'] . '</b>"';
        }

        if (isset($options['query']) && !empty($options['query'])) {
            $text .= 'по запросу "<b>' . $options['query'] . '</b>"';
        }

        if (isset($options['tag_id']) && !empty($options['tag_id'])) {
            $tags = $this->fetchAllTags();
            if (isset($tags[$options['tag_id']])) {
                $text .= ' с тегом "<b>' . $tags[$options['tag_id']]->getTagName() . '</b>"';
            }

        }

        if ($text) {
            $text .= '. <a href="/study">Показать все</a>';
        }

        return $text;
    }

    public function searchTerm($query, $page = 1)
    {
        if (!$query) {
            return array();
        }

        $select = $this->table->select()
                ->from($this->table, '*, MATCH (`term_name` , `term_info`) AGAINST ("' . $query . '") as rel')
                ->where('MATCH (`term_name` , `term_info`) AGAINST ("' . $query . '")')
                ->order('rel DESC');

        return $this->infoTerm($select, $page);
    }
}
